package com.chance.cc.crawler.development.scripts.yesmywine;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chance.cc.crawler.core.CrawlerEnum;
import com.chance.cc.crawler.core.CrawlerRecordContext;
import com.chance.cc.crawler.core.downloader.HttpConstant;
import com.chance.cc.crawler.core.downloader.HttpPage;
import com.chance.cc.crawler.core.downloader.HttpRequest;
import com.chance.cc.crawler.core.downloader.HttpRequestBody;
import com.chance.cc.crawler.core.pipeline.result.CrawlerData;
import com.chance.cc.crawler.core.record.CrawlerRequestRecord;
import com.chance.cc.crawler.core.script.crawler.CrawlerCommonScript;
import org.apache.commons.lang3.StringUtils;
import org.omg.CORBA.OBJ_ADAPTER;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.chance.cc.crawler.core.CrawlerEnum.CrawlerDataType.article;

/**
 * @author lt
 * @version 1.0
 * @date 2021-01-22 17:54:25
 * @email okprog@sina.com
 */
public class YesMyWineCrawlerScript extends CrawlerCommonScript {


    private Logger logger = LoggerFactory.getLogger(YesMyWineCrawlerScript.class);

    public static final String indexUrlRegex = "https?://appi6\\.yesmywine\\.com/mobile/app/chooseWine\\.jspa";
    public static final String listUrlRegex = "https:?//appi6\\.yesmywine\\.com/mobile/app/searchV3\\.jspa\\S*";
    public static final String productUrlRegex = "https:?//appi6\\.yesmywine\\.com/mobile/app/queryGoodsDetails_v3\\.jspa\\S*";

    public static final String listBaseUrl = "https://appi6.yesmywine.com/mobile/app/searchV3.jspa";
    public static final String productBaseUrl = "https://appi6.yesmywine.com/mobile/app/queryGoodsDetails_v3.jspa";

    @Override
    public List<CrawlerRequestRecord> parseLinks(CrawlerRequestRecord crawlerRecord, HttpPage page) {
        List<CrawlerRequestRecord> parsedLinks = new ArrayList<>();
        HttpRequest lastRequest = crawlerRecord.getHttpRequest();
        String lastRequestUrl = lastRequest.getUrl();
        if (lastRequestUrl.matches(indexUrlRegex)){
            return parseIndexLinks(crawlerRecord, page, parsedLinks);
        }
        if (lastRequestUrl.matches(listUrlRegex)){
            return parseListLinks(crawlerRecord, page, parsedLinks, lastRequest, lastRequestUrl);
        }
        return null;
    }

    private List<CrawlerRequestRecord> parseListLinks(CrawlerRequestRecord crawlerRecord, HttpPage page, List<CrawlerRequestRecord> parsedLinks, HttpRequest lastRequest, String lastRequestUrl) {
        String rawText = page.getRawText();
        rawText = rawText.substring(rawText.indexOf("\"") + 1, rawText.lastIndexOf("\""));
        JSONObject pageObj = JSONObject.parseObject(rawText);
        JSONArray goodsList = pageObj.getJSONArray("goodsList");
        if (goodsList.size() > 0){
            HttpRequestBody requestBody = lastRequest.getRequestBody();
            byte[] bytes = requestBody.getBody();
            String decodeStr = URLDecoder.decode(new String(bytes));
            String[] strings = decodeStr.split("=");
            Map<String, Object> params = new HashMap<>();
            JSONObject jsonObject = JSONObject.parseObject(strings[1]);
            String curPage = jsonObject.getString("curPage");
            jsonObject.replace("curPage",String.valueOf(Integer.parseInt(curPage) + 1));
            String jsonString = jsonObject.toJSONString();
            params.put(strings[0],jsonString);
            HttpRequestBody httpRequestBody = HttpRequestBody.form(params,"UTF-8");
            CrawlerRequestRecord nextPageRecord = CrawlerRequestRecord.builder()
                    .turnPageRequest(crawlerRecord)
                    .httpUrl(lastRequestUrl)
                    .recordKey(lastRequestUrl + System.currentTimeMillis())
                    .releaseTime(System.currentTimeMillis())
                    .copyBizTags()
                    .build();
            HttpRequest nextPageRequest = nextPageRecord.getHttpRequest();
            nextPageRequest.setMethod(HttpConstant.Method.POST);
            nextPageRequest.setRequestBody(httpRequestBody);
            nextPageRequest.addHeader("Host","appi6.yesmywine.com");
            parsedLinks.add(nextPageRecord);

            for (Object good : goodsList) {
                JSONObject goodObj = (JSONObject)good;
                String goodsId = goodObj.getString("goodsId");
                String productUrl = productBaseUrl + "?goodsId=" + goodsId;
                Map<String,Object> map = new HashMap<>();
                map.put("areaId","1");
                map.put("goodsId",goodsId);

                Map<String,Object> param = new HashMap<>();
                param.put("data", JSON.toJSONString(map));
                HttpRequestBody itemBody = HttpRequestBody.form(param,"UTF-8");
                CrawlerRequestRecord itemRecord = CrawlerRequestRecord.builder()
                        .itemPageRequest(crawlerRecord)
                        .httpUrl(productUrl)
                        .recordKey(productUrl)
                        .releaseTime(System.currentTimeMillis())
                        .copyBizTags()
                        .resultLabelTag(CrawlerEnum.CrawlerDataType.article)
                        .needParsed(false)
                        .needWashed(true)
                        .build();
                HttpRequest itemRequest = itemRecord.getHttpRequest();
                itemRequest.setRequestBody(itemBody);
                itemRequest.setMethod(HttpConstant.Method.POST);
                itemRequest.addHeader("Host","appi6.yesmywine.com");
                parsedLinks.add(itemRecord);
            }
        }
        return parsedLinks;
    }

    private List<CrawlerRequestRecord> parseIndexLinks(CrawlerRequestRecord crawlerRecord, HttpPage page, List<CrawlerRequestRecord> parsedLinks) {
        String rawText = page.getRawText();
        rawText = rawText.substring(rawText.indexOf("\"") + 1, rawText.lastIndexOf("\""));
        JSONObject pageObj = JSONObject.parseObject(rawText);
        JSONArray categoryList = pageObj.getJSONArray("categoryList");
        for (Object cate : categoryList) {
            JSONObject cateObj = (JSONObject)cate;
            if (!cateObj.getString("title").equals("酒具")){
                String paramValue = cateObj.getString("paramValue");
                String listUrl = listBaseUrl + "?param=" + paramValue;
                Map<String,Object> params = new HashMap<>();
                Map<String,Object> jsonMap = new HashMap<>();
                String[] filters = {"t99"};
                jsonMap.put("filter",filters);
                jsonMap.put("curPage","1");
                jsonMap.put("category",paramValue);
                String jsonString = JSON.toJSONString(jsonMap);
                params.put("data",jsonString);
                HttpRequestBody httpRequestBody = HttpRequestBody.form(params,"UTF-8");
                CrawlerRequestRecord listRecord = CrawlerRequestRecord.builder()
                        .turnPageRequest(crawlerRecord)
                        .httpUrl(listUrl)
                        .recordKey(listUrl + System.currentTimeMillis())
                        .releaseTime(System.currentTimeMillis())
                        .notFilterRecord()
                        .copyBizTags()
                        .build();
                HttpRequest listRequest = listRecord.getHttpRequest();
                listRequest.setMethod(HttpConstant.Method.POST);
                listRequest.setRequestBody(httpRequestBody);
                listRequest.addHeader("Host","appi6.yesmywine.com");
                parsedLinks.add(listRecord);
            }
        }
        return parsedLinks;
    }

    @Override
    public List<CrawlerData> washPage(CrawlerRequestRecord crawlerRecord, HttpPage page) {
        List<CrawlerData> crawlerDataList = new ArrayList<>();
        if (crawlerRecord.tagsCreator().resultTags().hasDataType(article)){
            crawlerDataList.addAll(washArticle(crawlerRecord, page));
        }
        return crawlerDataList;
    }

    private List<CrawlerData> washArticle(CrawlerRequestRecord crawlerRecord, HttpPage page) {
        List<CrawlerData> crawlerDataList = new ArrayList<>();
        String rawText = page.getRawText();
        rawText = rawText.substring(rawText.indexOf("\"") + 1, rawText.lastIndexOf("\""));
        JSONObject pageObj = JSONObject.parseObject(rawText);
        String productId = pageObj.getJSONObject("goodsInfo").getString("goodsId");
        CrawlerData crawlerData = CrawlerData.builder()
                .data(crawlerRecord,page)
                .url(crawlerRecord.getHttpRequest().getUrl())
                .releaseTime(System.currentTimeMillis())
                .dataId(StringUtils.joinWith("-",crawlerRecord.getDomain(),article.enumVal(),productId))
                .content(pageObj.getJSONObject("goodsInfo").toJSONString())
                .requestLabelTag(CrawlerEnum.CrawlerRequestType.result)
                .requestLabelTag(CrawlerEnum.CrawlerRequestType.filter)
                .build();


        crawlerDataList.add(crawlerData);
        return crawlerDataList;
    }

    @Override
    public void initUrlRegulars() {
        addUrlRegular(indexUrlRegex);
        addUrlRegular(listUrlRegex);
        addUrlRegular(productUrlRegex);
    }

    @Override
    public boolean crawlerCheck(CrawlerRequestRecord crawlerRecord) {
        return true;
    }

    @Override
    public void afterExecute(CrawlerRecordContext context) {

    }

    @Override
    public String domain() {
        return "yesmywine";
    }
}
